#include "../glutil/GLee.h"
#include "ground.h"
#include "math.h"
#include <QGLWidget>
#include <QImage>
#include <exception>
//#include "../dataengine/ShpTerrainFileManager.h"
//#include "../dataengine/TxtTerrainFileManager.h"
//#include "../glutil/TerrainRenderer.h"

Ground::Ground()
{

	//dataengine::ShpTerrainFileManager loader("data/ElevLines/elevation_lines_bb.sbx");
//	dataengine::ShpTerrainFileManager loader("data/malla-4000m_filab_xyz.shx");
//	dataengine::TxtTerrainFileManager loader("data/point_sets/cata_100k.txt"," ");
//	dataengine::TxtTerrainFileManager loader("data/poblacionUSA.txt"," ");
	//dataengine::TxtTerrainFileManager loader("data/codposUSA.txt"," ");
//	dataengine::TxtTerrainFileManager loader("data/random.txt"," ");
/*
	if(!loader.canLoadFile())
	{
		class terrainException: public std::exception
		{
			virtual const char* what() const throw(){ return "Could not load terrain file";	}
		};
		throw terrainException();
	}

	m_model = loader.loadFile();
	m_renderer = new glutil::ModelRenderer(m_model);
	glutil::GLInstanceInfo groundInfo;
	groundInfo.m_location[0] = 0.0;
	groundInfo.m_location[1] = 0.0;
	groundInfo.m_location[2] = 0.0;
	groundInfo.m_rotation[0] = 0;//90.0;
	groundInfo.m_rotation[1] = 90.0;
	groundInfo.m_rotation[2] = 0.0;
	groundInfo.m_scale = 1.0;
	m_renderer->addInstance(groundInfo);
*/
	m_groundShader = NULL;
}

Ground::~Ground()
{
//	delete m_renderer;
	delete m_groundShader;
}

void Ground::draw(float)
{
	if(m_groundShader == NULL)
	{
		m_groundShader = new glutil::ShaderProgram();
		m_groundShader->attachShaderFromFile(GL_VERTEX_SHADER, "data/ground.vert");
		m_groundShader->attachShaderFromFile(GL_FRAGMENT_SHADER, "data/ground.frag");
		m_groundShader->link();
		m_groundShader->setUniform1i("firstTexture",0);
		m_groundShader->setUniform1i("secondTexture",1);
	}
    drawGroundMound(40,30,30, 1);

	glColor4f(0.0,0.0,0.0,1.0);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
//	m_renderer->render(0,true);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

}

util::Pair<float> Ground::getSegmentedCirclePoint(float radius, int segments, int currentPoint)
{
    float angle = 2*M_PI/segments * currentPoint;
	util::Pair<float> p;
    p[0] = radius * cos(angle);
    p[1] = radius * sin(angle);

    return p;
}

float Ground::getGroundCircleHeight(float radius, float now)
{
   	return 0; 
    return 10 * cos(now/radius) - 10;
}


void Ground::drawGroundMound(float radius, int segmentsPerCircle, int circles, float opacity)
{
	m_groundShader->bind();
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_TEXTURE_2D);

	const float texScale[2] = {24.0, 0.7};
    // We draw the center fan
	const float disp[2] = {0.4,0.2};
    glBegin(GL_TRIANGLE_FAN);
        glMultiTexCoord2f(GL_TEXTURE0,disp[0],disp[1]); 
        glMultiTexCoord2f(GL_TEXTURE1,0,0); 
        glColor4f(1,1.0,1,1);
        glNormal3f(0,1,0);
        glVertex3f(0,getGroundCircleHeight(radius,0),0);
        for(int i = 0; i<= segmentsPerCircle;++i)
        {    
			util::Pair<float> p = getSegmentedCirclePoint(radius/circles,segmentsPerCircle,i);
            glColor4f(1,1,1,(1-1.0/circles)*opacity);
            glMultiTexCoord2f(GL_TEXTURE0,p[0]/texScale[0]+disp[0],p[1]/texScale[0]+disp[1]); 
            glMultiTexCoord2f(GL_TEXTURE1,p[0]/texScale[1],p[1]/texScale[1]); 
            glVertex3f(p[0],getGroundCircleHeight(radius, radius/circles), p[1]);
        }
    glEnd();

    // We draw the surrounding quads
    for(int i=1; i<circles-1;++i)
    {
        glBegin(GL_QUAD_STRIP);
            for(int j=0;j<=segmentsPerCircle;++j)
            {
				util::Pair<float> p1 = getSegmentedCirclePoint(radius/circles*i,segmentsPerCircle,j);
                glColor4f(1,1,1,(1-(((float)(i))/circles))*opacity);
                glMultiTexCoord2f(GL_TEXTURE0,p1[0]/texScale[0]+disp[0],p1[1]/texScale[0]+disp[1]); 
                glMultiTexCoord2f(GL_TEXTURE1,p1[0]/texScale[1],p1[1]/texScale[1]); 
                glVertex3f(p1[0],getGroundCircleHeight(radius,radius/circles*i),p1[1]);

				util::Pair<float> p2 = getSegmentedCirclePoint(radius/circles*(i+1),segmentsPerCircle,j);
                glColor4f(1,1,1,(1-(((float)((i+1)))/circles))*opacity);
                glMultiTexCoord2f(GL_TEXTURE0,p2[0]/texScale[0]+disp[0],p2[1]/texScale[0]+disp[1]); 
                glMultiTexCoord2f(GL_TEXTURE1,p2[0]/texScale[1],p2[1]/texScale[1]); 
                glVertex3f(p2[0],getGroundCircleHeight(radius,radius/circles*(i+1)),p2[1]);
            }
        glEnd();
    }

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
	m_groundShader->unbind();
}



